package wang.chunfan.mybatis.log;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.omg.CORBA.OBJ_ADAPTER;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import wang.chunfan.mybatis.dao.BaseDao;
import wang.chunfan.mybatis.dao.LoginLogDao;
import wang.chunfan.mybatis.pojo.AbstractLog;
import wang.chunfan.mybatis.pojo.LoginLog;
import wang.chunfan.mybatis.redis.RedisKeys;

import java.util.concurrent.*;

@Component
public class LogConsumer implements CommandLineRunner {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    LoginLogDao loginLogDao;

    @Autowired
    ApplicationContext applicationContext;

    private ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("log-consumer-schedule-pool-%d").setDaemon(true).build();

    private ScheduledExecutorService pool = new ScheduledThreadPoolExecutor(1, namedThreadFactory);

    @Override
    public void run(String... args) throws Exception {
        // 创建并执行一个在给定初始延迟后首次启用的定期操作，后续操作具有给定的周期；
        // 也就是将在 initialDelay 后开始执行，然后在 initialDelay+period 后执行，接着在 initialDelay + 2 * period 后执行，依此类推
        // pool.scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

        //  创建并执行一个在给定初始延迟后首次启用的定期操作，随后，在每一次执行终止和下一次执行开始之间都存在给定的延迟
        pool.scheduleWithFixedDelay(() -> receiveQueue(), 1, 10, TimeUnit.SECONDS);
    }

    private void receiveQueue() {
        for (int i = 0; i < 100; i++) {
            try {
                AbstractLog log = (AbstractLog) redisTemplate.opsForList().rightPop(RedisKeys.getLogKey());
                if (log == null) {
                    return;
                }
                BaseDao dao = (BaseDao) applicationContext.getBean(log.getType() + "Dao");
                dao.insert(log);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
